package cash.cmp.personal_financial_system.controller;

import cash.cmp.personal_financial_system.model.account.Account;
import cash.cmp.personal_financial_system.model.Bill;
import cash.cmp.personal_financial_system.model.User;
import cash.cmp.personal_financial_system.service.impl.AccountServiceImpl;
import cash.cmp.personal_financial_system.service.impl.BillServiceImpl;
import cash.cmp.personal_financial_system.service.impl.UserServiceImpl;
import cash.cmp.personal_financial_system.utils.Result;
import cash.cmp.personal_financial_system.utils.easyexcel.listener.AdminBillExcelListener;
import cash.cmp.personal_financial_system.utils.easyexcel.listener.BillExcelListener;
import cash.cmp.personal_financial_system.utils.easyexcel.listener.UserExcelListener;
import com.alibaba.excel.EasyExcel;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;

@RestController
@RequestMapping("/excel")
public class ExcelController {

    @Autowired
    AccountServiceImpl accountService;
    @Autowired
    BillServiceImpl billService;
    @Autowired
    UserServiceImpl userService;

    @RequestMapping("/getUserBill")
    public void getUserBill( HttpServletResponse response) throws IOException{
        Account account = (Account) SecurityUtils.getSubject().getPrincipal();
        Integer id = account.getId();
        List<Bill> bills = billService.findBill(id);
        User user = userService.findUserById(id);
        String filename = user.getName()+"的账单";
        response.setContentType("application/vnd.ms-excel");
        // 对响应客户请求进行重新编码
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(filename, "utf-8");
        // 为导出文件设置默认名称，这里是测试导出
        response.setHeader("Content-disposition", "attachment;filename="+fileName+".xlsx");
        Set<String> excludeColumnFiledNames = new HashSet<String>();
        excludeColumnFiledNames.add("id");
        EasyExcel.write(response.getOutputStream(), Bill.class).excludeColumnFieldNames(excludeColumnFiledNames).sheet("1").doWrite(bills);
    }

    @RequiresRoles("admin")
    @RequestMapping("/getAllBill")
    public void getAllBill(HttpServletResponse response) throws IOException{
        List<Bill> bills = billService.findAllBill();
        String filename = "所有账单";
        response.setContentType("application/vnd.ms-excel");
        // 对响应客户请求进行重新编码
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(filename, "utf-8");
        // 为导出文件设置默认名称，这里是测试导出
        response.setHeader("Content-disposition", "attachment;filename="+fileName+".xlsx");
        EasyExcel.write(response.getOutputStream(), Bill.class).sheet("1").doWrite(bills);
    }

    @RequiresRoles("admin")
    @RequestMapping("/getAllUser")
    public void getAllUser(HttpServletResponse response) throws IOException{
        List<User> users = userService.findAllUser();
        String filename = "所有用户信息";
        response.setContentType("application/vnd.ms-excel");
        // 对响应客户请求进行重新编码
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(filename, "utf-8");
        // 为导出文件设置默认名称，这里是测试导出
        response.setHeader("Content-disposition", "attachment;filename="+fileName+".xlsx");
        EasyExcel.write(response.getOutputStream(), User.class).sheet("1").doWrite(users);
    }

    /**
     * 导入Excel
     * 后期做安全管理
     */
    //参数为excel文件和一个包含id的json
    @RequestMapping("/importBillExcelByUser")
    public Result importBillExcelByUser(@RequestPart MultipartFile file) throws IOException{
        //不能同时上传文件和json封装，所以再controller里解析
        //调用核心类的方法
        //书写方法记录有多少条没导入
        Account account = (Account) SecurityUtils.getSubject().getPrincipal();
        //记录错误信息
        List<String> msgList = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), Bill.class, new BillExcelListener(billService,account.getId(),msgList)).sheet().doRead();
        if(msgList.size() != 0) return Result.fail("fail",msgList);
        else{
            return Result.succ(200,"success",null);
        }
    }

    /**
     * 管理员导入Excel表内必须有用户id
     * 后期做安全管理
     */
    @RequestMapping("/importBillExcel")
    public Result importBillExcel(@RequestPart MultipartFile file) throws IOException{
        List<String> msgList = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), Bill.class, new AdminBillExcelListener(billService,msgList)).sheet().doRead();
        if(msgList.size() != 0) return Result.fail("fail",msgList);
        else{
            return Result.succ(200,"success",null);
        }
    }

    /**
     * 管理员导入用户信息表内必须有用户电话
     * 后期做安全管理
     */
    @RequestMapping("/importUserExcel")
    //返回错误信息，成功返回用户tel与密码
    public Result importUserExcel(@RequestPart MultipartFile file) throws IOException{
        Map<String,String> accounts = new HashMap<>();
        List<String> msgList = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), User.class, new UserExcelListener(userService,accountService,msgList,accounts)).sheet().doRead();
        if(msgList.size() != 0){
            return Result.fail("fail",msgList);
        }
        else{
            // accounts ，导入的用户tel，password，返回给前端
            return Result.succ(200,"success",accounts);
        }
    }


}
